package com.itheima.reggie.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.Page;
import com.itheima.reggie.mapper.DishFlavorMapper;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class DishServiceImpl implements DishService {

    @Autowired(required = false)
    private DishMapper dishMapper;

    @Autowired(required = false)
    private DishFlavorMapper dishFlavorMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 添加菜品
     *
     * @param dishDto
     * @return
     */
    @Transactional   //springboot默已经开启了事务注解扫描,所以这里直接使用就可以了
    @Override
    public boolean save(DishDto dishDto) {
        //1.完善菜品对象数据
        //(修改时间.添加时间.sort默认0.是否禁售设置1起售)
        dishDto.setUpdateTime(LocalDateTime.now());
        dishDto.setCreateTime(LocalDateTime.now());
        dishDto.setSort(0);
        dishDto.setStatus(1);

        //2.调用数据访问层添加菜品,要求获取到添加后菜品主键id
        dishMapper.insert(dishDto); //插入后里面就有菜品id

        //3.遍历口味记录列表完善数据
        List<DishFlavor> dishFlavorList = dishDto.getFlavors().stream().map((dishFlavor -> {
            //dishFlavor 是获取集合中的每个元素对象
            // (设置菜品主键.更新时间.创建时间.更新人.创建人)
            dishFlavor.setDishId(dishDto.getId());
            dishFlavor.setUpdateTime(LocalDateTime.now());
            dishFlavor.setCreateTime(LocalDateTime.now());
            dishFlavor.setUpdateUser(dishDto.getUpdateUser());
            dishFlavor.setCreateUser(dishDto.getCreateUser());
            return dishFlavor;

        })).collect(Collectors.toList());

        //4.调用数据访问层插入多条口味记录数据
        dishFlavorMapper.save(dishFlavorList);

         //清楚缓存
        //清楚缓存
        Set keys = redisTemplate.keys("dish_");  //获取以dish_xxx开头的key
        redisTemplate.delete(keys);   //删除这些key

        return true;
    }

    /**
     * 分页查询(连表查)
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @Override
    public Page<DishDto> findByPage(Integer page, Integer pageSize, String name) {

        //注意:对哪一条sql语句生成分页sql语句,这三句必须紧挨着
        PageHelper.startPage(page, pageSize);
        List<DishDto> all = dishMapper.findAll(name);
        PageInfo<DishDto> dishDtoPageInfo = new PageInfo<>(all);
        Page<DishDto> objectPage = new Page<>();
        objectPage.setRecords(dishDtoPageInfo.getList());
        objectPage.setTotal(dishDtoPageInfo.getTotal());

        return objectPage;


    }

    /**
     * 根据id查询指定菜品和多种口味
     *
     * @param id
     * @return
     */
    @Override
    public DishDto findById(Long id) {
        return dishMapper.findById(id);
    }

    /**
     * 通过id修改菜品
     *
     * @param dishDto
     * @return
     */
    @Override
    @Transactional
    public boolean updateById(DishDto dishDto) {
        //1.补全修改信息
        dishDto.setUpdateTime(LocalDateTime.now());

        //2.修改菜品
        dishMapper.updateById(dishDto);

        //3.删除该菜品的所有口味信息
        dishFlavorMapper.deleteById(dishDto.getId());

        //4.补全口味信息,然后重新插入
        List<DishFlavor> flavors = dishDto.getFlavors();
        List<DishFlavor> dishFlavorList = flavors.stream().map((dishFlavor -> {

            // (设置菜品主键.更新时间.创建时间.更新人.创建人)
            dishFlavor.setDishId(dishDto.getId());
            dishFlavor.setUpdateTime(LocalDateTime.now());
            dishFlavor.setCreateTime(LocalDateTime.now());
            dishFlavor.setUpdateUser(dishDto.getUpdateUser());
            dishFlavor.setCreateUser(dishDto.getCreateUser());
            return dishFlavor;

        })).collect(Collectors.toList());
        //5.批量保存口味信息
        dishFlavorMapper.save(dishFlavorList);

        //清楚缓存
        Set keys = redisTemplate.keys("dish_");  //获取以dish_xxx开头的key
        redisTemplate.delete(keys);   //删除这些key


        return true;

    }

    /**
     * 根据类别id查询菜品列表(添加套餐中)
     *
     * @param categoryId
     * @return
     */
    @Override
    public List<Dish> findByCategoryId(Long categoryId) {

        return dishMapper.findByCategoryId(categoryId);
    }


    /**
     * 根据类别和状态查询菜品列表List<DishDto>
     *
     * @param categoryId
     * @param status
     * @return
     */
    @Override
    public List<DishDto> findByCategoryId(Long categoryId, Integer status) {

        //0.从缓存中获取数据,缓存的key="dish_"+categoryId+"_"+status
        String key = "dish_" + categoryId + "_" + status;
        List<DishDto> dishDtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);
        //查询到为null,调用数据库查询
        if (dishDtoList == null) {

            //1.调用mapper根据类别id和状态查询菜品列表
            List<Dish> dishList = dishMapper.findByCategoryAndStatus(categoryId, status);

            //2.加工处理dishList封装到List<DishDao>,完善里面口味列表数据
            dishDtoList = dishList.stream().map((dish -> {
                //实例DishDao对象封装数据
                DishDto dishDto = new DishDto();

                //将dish对象所有数据赋值给dishDto里面去
                BeanUtils.copyProperties(dish, dishDto);

                //根据菜品id获取口味列表数据封装到dishDto里面区
                List<DishFlavor> dishFlavorList = dishFlavorMapper.findByDishId(dishDto.getId());
                dishDto.setFlavors(dishFlavorList);

                //返回dto对象
                return dishDto;

            })).collect(Collectors.toList());
        }

        // 将数据库中查询到的数据写入缓存
        redisTemplate.opsForValue().set(key, dishDtoList);

        //返回数据
        return dishDtoList;
    }


}